import os
import subprocess
import time
from pages.excel_data_extraction import Excel_data_extraction
from config.settings import get_config
from base.base_page import BasePage


"""
封装功能函数

"""
class Ext_Req_Header_Filter(BasePage):
    def __init__(self, driver, device_type, logger=None):
        super().__init__(driver, device_type, logger=logger)  # 传递日志实例
        self.driver = driver
        self.config = get_config(device_type)  # 获取全局配置
        self.excel_processor = Excel_data_extraction(self.driver, device_type, logger=logger)

    def create_new_req_header_filter(self, interface_name, parameter_position, req_header_word,
                                      operator, req_header_content):
        # 进入请求头改写界面
        self.enter_ext_req_header_filter()
        # 停止指定请求头过滤策略状态
        self.update_req_header_filter_status(interface_name, req_header_filter_status='停止')
        # 删除指定请求头过滤策略
        self.delete_req_header_filter(interface_name)
        # 新建请求头过滤策略
        self.newly_req_header_filter()
        # 输入请求头字段选择的数据接口名称
        self.input_data_interface(interface_name)
        # 输入请求头参数位置
        self.input_parameter_position(parameter_position)
        # 输入请求头字段
        self.input_req_header_word(req_header_word)
        # 输入运算符
        self.input_operator(operator)
        # 输入字符内容值
        self.input_req_header_content(req_header_content)
        # 保存请求头过滤配置策略
        self.save_req_header_filter(interface_name)


    def enter_ext_req_header_filter(self):
        """ 进入新建对外传输数据接口敏感词过滤配置 """
        status = self.find_element('first_level_menu_module', 'interface_security_configure_status')
        if "ivu-menu-opened" in status.get_attribute("class"):
            pass
        else:
            self.click('first_level_menu_module', 'interface_security_configure')
        status = self.find_element('second_level_menu_module', 'ext_service_transmit_security_status')
        if "ivu-menu-opened" in status.get_attribute("class"):
            pass
        else:
            self.click('second_level_menu_module', 'ext_service_transmit_security_status')
        status = self.find_element('third_fourth_level_menu_module', 'ext_transmit_enhanced_security')
        if "ivu-menu-opened" in status.get_attribute("class"):
            if self.quick_check_element('ext_req_header_filter', 'req_parameter_position_title'):
                pass
            else:
                self.click('third_fourth_level_menu_module', 'ext_transmit_req_header_filter')
        else:
            self.click('third_fourth_level_menu_module', 'ext_transmit_enhanced_security')
            self.click('third_fourth_level_menu_module', 'ext_transmit_req_header_filter')
            self.soft_assert_element_visible('ext_req_header_filter', 'req_parameter_position_title')

    def newly_req_header_filter(self):
        """ 点击新建按钮 """
        self.click('common_elements', 'newly_built')
        self.soft_assert_element_visible('ext_req_header_filter', 'input_data_interface')

    def input_data_interface(self, interface_name):
        """ 输入数据接口 """
        self.click('ext_req_header_filter', 'input_data_interface')
        selected_result = self.select_interface_options(
            element_locator='input_data_interface_all',
            values=interface_name,
            param_name='interface_name'
        )
        return selected_result

    def input_parameter_position(self, parameter_position):
        """ 输入参数位置 """
        self.click('ext_req_header_filter', 'input_parameter_position')
        selected_result = self.select_interface_options(
            element_locator='input_parameter_position_all',
            values=parameter_position,
            param_name='parameter_position'
        )
        return selected_result

    def input_req_header_word(self, req_header_word):
        """ 输入请求头字段 """
        self.input_text('ext_req_header_filter', 'input_req_header_word', req_header_word)
        self.soft_assert_input_value('ext_req_header_filter', 'input_req_header_word', req_header_word)

    def input_operator(self, operator):
        """ 输入运算符 """
        self.click('ext_req_header_filter', 'input_operator')
        selected_result = self.select_interface_options(
            element_locator='input_operator_all',
            values=operator,
            param_name='operator'
        )
        return selected_result

    def input_req_header_content(self, req_header_content):
        """ 输入字段内容值 """
        self.input_text('ext_req_header_filter', 'input_req_header_content', req_header_content)
        self.soft_assert_input_value('ext_req_header_filter', 'input_req_header_content', req_header_content)

    def save_req_header_filter(self, interface_name):
        # 保存
        self.click('ext_req_header_filter', 'save_req_header_filter')
        if self.find_element('common_elements', 'add_success'):
            self.find_req_header_filter_name(interface_name)
            self.logger.info(f'{interface_name}的请求头过滤配置保存成功')

    def update_req_header_filter_status(self, interface_name, req_header_filter_status):
        """ 修改状态 """
        self.enter_ext_req_header_filter()
        if self.quick_check_element('common_elements', 'no_data'):
            pass
        else:
            result =  self.query_paged_data(
                search_locator='get_req_header_filter_name',
                target_locator='get_req_header_filter_status_all',
                value=interface_name,
                param_name='interface_name'
            )
            if result is None:
                pass
            else:
                if "ivu-switch-checked" in result.get_attribute("class"):
                    if req_header_filter_status == '启动':
                        pass
                    else:
                        result.click()
                        self.find_element('common_elements', 'status_update_success')
                        self.logger.info(f"'{interface_name}'的请求头过滤配置：停止成功")
                else:
                    if req_header_filter_status == '停止':
                        pass
                    else:
                        result.click()
                        self.find_element('common_elements', 'status_update_success')
                        self.logger.info(f" '{interface_name}'的请求头过滤配置：启动成功")

    def delete_req_header_filter(self, interface_name):
        """
        支持分页查找并删除对象
        :param interface_name: 要删除的对象名称
        """
        if self.quick_check_element('common_elements', 'no_data'):
            pass
        else:
            current_page = 1
            while True:
                # 获取当前页所有对象名称
                name_elements = self.find_elements('ext_req_header_filter',
                                                   'get_req_header_filter_name')
                # 遍历当前页
                for row_index, element in enumerate(name_elements, 1):
                    if element.text.strip() == interface_name:
                        self._delete_current_row(row_index)
                        if self.quick_check_element('common_elements', 'delete_success'):
                            self.logger.info(f"成功删除第{current_page}页的'{interface_name}'")
                        else:
                            self.logger.info(f"未成功删除第{current_page}页的'{interface_name}'")
                        return
                # 尝试翻页
                if not self._go_to_next_page():
                    break
                current_page += 1 # 等待分页加载

    def _delete_current_row(self, row_index):
        """执行单行删除操作"""
        delete_btn = self.find_dynamic_element(
            'ext_req_header_filter',
            'get_delete_req_header_filter_all',
            row_index
        )
        # 点击删除按钮
        delete_btn.click()
        self.click('common_elements', 'confirm_button')
        self.find_element('common_elements', 'delete_success')

    """##########################################  查找界面是否存在指定数据  ##########################################"""

    def find_req_header_filter_name(self, interface_name):
        """ 查看界面是否存在保存的接口名称 """
        selected_result = self.select_interface_options(
            element_locator='get_req_header_filter_name',
            values=interface_name,
            param_name='interface_name'
        )
        return selected_result

    def find_parameter_position(self, parameter_position):
        """ 查看界面是否存在接口名称的参数位置 """
        selected_result = self.select_interface_options(
            element_locator='get_parameter_position',
            values=parameter_position,
            param_name='parameter_position'
        )
        return selected_result

    def find_req_header_word(self, req_header_word):
        """ 查看界面是否存在接口名称的请求头字段 """
        selected_result = self.select_interface_options(
            element_locator='get_req_header_field',
            values=req_header_word,
            param_name='req_header_word'
        )
        return selected_result

    def find_create_time(self, interface_name):
        """ 查看界面是否存在接口名称的创建时间 """
        selected_result = self.select_interface_options(
            element_locator='get_create_time',
            values=interface_name,
            param_name='interface_name'
        )
        return selected_result

    """##########################################  筛选  ##########################################"""

    def select_interface_name(self, interface_name):
        """筛选数据接口名称"""
        self.enter_ext_req_header_filter()
        self.click('ext_req_header_filter', 'select_interface_name')
        selected_result = self.select_interface_options(
            element_locator='select_interface_name_all',
            values=interface_name,
            param_name='interface_name'
        )
        self.soft_assert_input_value('ext_req_header_filter', 'select_interface_name', interface_name)
        return selected_result

    def select_parameter_position(self, parameter_position):
        """筛选参数位置"""
        self.enter_ext_req_header_filter()
        self.click('ext_req_header_filter', 'select_parameter_position')
        selected_result = self.select_interface_options(
            element_locator='select_parameter_position_all',
            values=parameter_position,
            param_name='parameter_position'
        )
        self.soft_assert_input_value('ext_req_header_filter', 'select_parameter_position', parameter_position)
        return selected_result

    def select_req_header_word(self, req_header_word):
        """筛选请求头字段"""
        self.enter_ext_req_header_filter()
        self.click('ext_req_header_filter', 'select_req_header_word')
        selected_result = self.select_interface_options(
            element_locator='select_req_header_word_all',
            values=req_header_word,
            param_name='req_header_word'
        )
        self.soft_assert_input_value('ext_req_header_filter', 'select_req_header_word', req_header_word)
        return selected_result

    def select_operator(self, operator):
        """筛选运算符"""
        self.enter_ext_req_header_filter()
        self.click('ext_req_header_filter', 'select_operator')
        selected_result = self.select_interface_options(
            element_locator='select_operator_all',
            values=operator,
            param_name='operator'
        )
        self.soft_assert_input_value('ext_req_header_filter', 'select_operator', operator)
        return selected_result
    """##########################################  指定接口获取界面数据  ##########################################"""

    def get_parameter_position(self, interface_name):
        """获取指定接口的参数位置 """
        self.enter_ext_req_header_filter()
        result =  self.query_paged_data(
            search_locator='get_req_header_filter_name',
            target_locator='get_parameter_position_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的参数位置：{result}")
        return result

    def get_req_header_field(self, interface_name):
        """获取指定接口的请求头字段 """
        self.enter_ext_req_header_filter()
        result =  self.query_paged_data(
            search_locator='get_req_header_filter_name',
            target_locator='get_req_header_field_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的请求头字段：{result}")
        return result

    def get_numerical_value(self, interface_name):
        """获取指定接口的请求头内容 """
        self.enter_ext_req_header_filter()
        result =  self.query_paged_data(
            search_locator='get_req_header_filter_name',
            target_locator='get_numerical_value_all',
            value=interface_name,
            param_name='interface_name'
        ).text.strip()
        self.logger.info(f"找到接口 '{interface_name}' 的请求头内容：{result}")
        return result

    """##########################################  导入导出  ##########################################"""

    def export(self):
        # 导出
        self.click('common_elements', 'export')
        excel_file = self.excel_processor.wait_for_new_excel(timeout=60)
        return excel_file

    def export_req_header_filter(self, interface_name, parameter_position, req_header_word, operator, req_header_content, create_time):
        excel_file = self.export()
        # 定义解析参数
        parse_params = {
            "sheet_name": "1-100",
            "start_row": 3,
            "headers": ["序号", "数据接口名称", "参数位置", "参数名称", "运算符", "数值", "创建时间"],
            "max_rows": 10
        }

        # 解析Excel内容
        excel_data = self.excel_processor.parse_excel(excel_file, parse_params)

        # 只处理第一个数据条目
        for item in excel_data:
            # 记录完整数据
            self.logger.info("正在验证导出的请求头改写数据：")
            for key, value in item.items():
                self.logger.info(f"{key}: {value}")

            # 数据预处理
            excel_values = {
                '数据接口名称': str(item.get('数据接口名称', '')).strip(),
                '参数位置': str(item.get('参数位置', '')).strip(),
                '参数名称': str(item.get('参数名称', '')).strip(),
                '运算符': str(item.get('运算符', '')).strip(),
                '数值': str(item.get('数值', '')).strip(),
                '创建时间': str(item.get('创建时间', '')).strip()
            }

            # 字段比较验证
            comparisons = [
                ('数据接口名称', excel_values['数据接口名称'], interface_name),
                ('参数位置', excel_values['参数位置'], parameter_position),
                ('参数名称', excel_values['参数名称'], req_header_word),
                ('运算符', excel_values['运算符'], operator),
                ('数值', excel_values['数值'], req_header_content),
                ('创建时间', excel_values['创建时间'], create_time)
            ]

            # 执行所有字段比较
            all_match = True
            for field, actual, expected in comparisons:
                # 统一None处理
                actual = actual if actual != 'None' else None
                expected = str(expected).strip() if expected is not None else None
                if actual == expected:
                    self.logger.info(f"{field}匹配成功: {actual}")
                else:
                    all_match = False
                    self.logger.error(f"{field}匹配失败 | Excel值: {actual} | 期望值: {expected}")
            # 输出最终结果
            if all_match:
                self.logger.info("所有字段验证通过")
            else:
                self.logger.error("存在字段验证失败")
            # 无论是否匹配，执行一次后退出循环
            break

    def access_req_header_filter(self, *fields):
        field_map = {
            "interface_name": "first_interface_name",
            "parameter_position": "first_parameter_position",
            "req_header_word": "first_req_header_word",
            "operator": "first_operator",
            "req_header_content": "first_req_header_content",
            "create_time": "first_create_time"
        }
        # 如果没有传参，默认返回全部字段（保持原顺序）
        if not fields:
            fields = ("interface_name", "req_header_field", "req_header_content", "create_time")
        # 根据映射关系获取值
        result = []
        for field in fields:
            mapped_field = field_map.get(field)
            if not mapped_field:  # 处理无效参数名
                raise ValueError(f"无效参数名: {field}")
            result.append(self.get_element_text("ext_req_header_filter", mapped_field))
        # 如果只传单个参数，直接返回标量值（可选）
        return tuple(result) if len(result) > 1 else result[0] if result else None

    """##########################################  通用函数  ##########################################"""

    def query_paged_data(self, search_locator: str, target_locator: str, value: str, param_name: str):
        """通用分页数据查询方法（返回符合的元素、单值）"""
        # 标准化输入值
        target_text = str(value).strip()
        current_page = 1

        while True:
            # 获取当前页所有可选项
            options = self.find_elements('ext_req_header_filter', search_locator)

            # 遍历匹配选项
            for row_index, element in enumerate(options, 1):
                option_text = element.text.strip()
                if option_text == target_text:
                    # 获取同行的目标元素
                    target_element = self.find_dynamic_element(
                        'ext_req_header_filter',
                        target_locator,
                        row_index
                    )
                    return target_element  # 直接返回元素
                    # return target_element.text.strip() #直接返回字符串

            # 尝试翻页
            if not self._go_to_next_page():
                self.logger.debug(f"未找到匹配项: {target_text}，已遍历 {current_page} 页")
                return None  # 静默返回None

            current_page += 1

    def select_interface_options(self, element_locator: str, values: list, param_name: str):
        """通用接口选项选择方法（基础方法）"""
        # 类型统一处理
        if not isinstance(values, list):
            values = [values]

        selected = []
        for value in values:
            # 获取所有可选项
            options = self.find_elements('ext_req_header_filter', element_locator)

            # 标准化输入值
            target_text = str(value).strip()

            # 遍历匹配选项
            found = False
            for option in options:
                option_text = option.text.strip()
                if option_text == target_text:
                    self.highlight_element(option)  # 可视化点击元素
                    option.click()
                    selected.append(option_text)
                    found = True
                    break

            if not found:
                available_options = [opt.text.strip() for opt in options]
                raise ValueError(
                    f"参数 {param_name} 未找到选项: '{target_text}'\n"
                    f"可用选项: {available_options}"
                )
            return selected

